﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using UnityEngine.Profiling;

namespace ProjScan.Tools
{
	// Token: 0x02000168 RID: 360
	internal class PerformanceMeasurer : Singleton<PerformanceMeasurer>
	{
		// Token: 0x06000CCC RID: 3276 RVA: 0x0000683A File Offset: 0x00004A3A
		public void Init()
		{
			this.ResetStatusState();
			this.ResetStatusList();
			this.ResetValue();
		}

		// Token: 0x06000CCD RID: 3277 RVA: 0x00006852 File Offset: 0x00004A52
		private void ResetStatusState()
		{
			this.currentPerformanceBaseline = new PerformanceMeasurer.CurrentStatusState();
			this.stateExecutionStopwatch = new Stopwatch();
			this.stateTrackerStack = new Stack<PerformanceMeasurer.StateTracker>();
		}

		// Token: 0x06000CCE RID: 3278 RVA: 0x00006876 File Offset: 0x00004A76
		private void ResetValue()
		{
			this.maxCpuUsage = 0.0;
			this.maxMemUsage = 0.0;
			this.elapsedTime = 0f;
		}

		// Token: 0x06000CCF RID: 3279 RVA: 0x000068A2 File Offset: 0x00004AA2
		public void RecordMaxValues()
		{
			this.maxCpuUsage = Math.Max(this.maxCpuUsage, PerformanceMeasurer.CurrentStatusState.GetFirstMeasurement());
			this.maxMemUsage = Math.Max(this.maxMemUsage, PerformanceMeasurer.CurrentStatusState.GetSecondMeasurement());
		}

		// Token: 0x06000CD0 RID: 3280 RVA: 0x00038F8C File Offset: 0x0003718C
		public void WritePerformanceDataToFile()
		{
			using (StreamWriter streamWriter = new StreamWriter(ToolsHelper.GetScanOutPut() + "/GlobalInfo"))
			{
				streamWriter.WriteLine(this.elapsedTime);
				streamWriter.WriteLine(this.maxCpuUsage);
				streamWriter.WriteLine(this.maxMemUsage);
			}
		}

		// Token: 0x06000CD1 RID: 3281 RVA: 0x000068D1 File Offset: 0x00004AD1
		public void PushState(string entryStatusName)
		{
			this.stateTrackerStack.Push(new PerformanceMeasurer.StateTracker(entryStatusName));
		}

		// Token: 0x06000CD2 RID: 3282 RVA: 0x000068E6 File Offset: 0x00004AE6
		public void CloseAndRecordState()
		{
			this.stateTrackerStack.Pop().RecordStateStatus();
		}

		// Token: 0x06000CD3 RID: 3283 RVA: 0x00038FF8 File Offset: 0x000371F8
		public void StartStateExecutionMeasure(string entryLabel)
		{
			bool flag = this.stateTrackerStack == null || this.stateTrackerStack.Count == 0;
			if (flag)
			{
				throw new Exception("Has not enter module");
			}
			this.stateExecutionStopwatch.Reset();
			this.stateExecutionStopwatch.Start();
			this.currentPerformanceBaseline.StartMeasurement();
			this.stateTrackerStack.Peek().labelStack.Push(entryLabel);
		}

		// Token: 0x06000CD4 RID: 3284 RVA: 0x0003906C File Offset: 0x0003726C
		public void StopStateExecutionMeasure(long ticks)
		{
			bool flag = this.stateTrackerStack == null;
			if (flag)
			{
				ScanLog.UnityLogError("ModuleStack is null");
			}
			else
			{
				bool flag2 = this.stateTrackerStack.Count == 0;
				if (flag2)
				{
					ScanLog.UnityLogError("ModuleStack is empty");
				}
				else
				{
					bool flag3 = this.stateTrackerStack.Peek().labelStack.Count != 0;
					if (flag3)
					{
						long elapsedMilliseconds = this.stateExecutionStopwatch.ElapsedMilliseconds;
						this.stateExecutionStopwatch.Stop();
						double primaryValue = this.currentPerformanceBaseline.FirstMeasure();
						double secondaryValue = this.currentPerformanceBaseline.SecondMeasure();
						this.stateTrackerStack.Peek().RecordSnapshot(ticks, elapsedMilliseconds, primaryValue, secondaryValue);
					}
				}
			}
		}

		// Token: 0x06000CD5 RID: 3285 RVA: 0x000068FA File Offset: 0x00004AFA
		private void ResetStatusList()
		{
			this.checkpointStopwatch = new Stopwatch();
			this.statusCheckpointList = new List<PerformanceMeasurer.StatusCheckpoint>();
		}

		// Token: 0x06000CD6 RID: 3286 RVA: 0x00006913 File Offset: 0x00004B13
		public void StartCheckpointMeasure()
		{
			this.checkpointStopwatch.Reset();
			this.checkpointStopwatch.Start();
		}

		// Token: 0x06000CD7 RID: 3287 RVA: 0x00039120 File Offset: 0x00037320
		public void AddExecutionCheckpoint(string checkpointLabel)
		{
			float checkpointTime = (float)this.checkpointStopwatch.ElapsedMilliseconds;
			PerformanceMeasurer.StatusCheckpoint item = default(PerformanceMeasurer.StatusCheckpoint);
			item.checkpointLabel = checkpointLabel;
			item.checkpointTime = checkpointTime;
			item.primaryValue = PerformanceMeasurer.CurrentStatusState.GetFirstMeasurement();
			item.secondaryValue = PerformanceMeasurer.CurrentStatusState.GetSecondMeasurement();
			bool flag = this.statusCheckpointList == null;
			if (flag)
			{
				this.statusCheckpointList = new List<PerformanceMeasurer.StatusCheckpoint>();
			}
			this.statusCheckpointList.Add(item);
		}

		// Token: 0x06000CD8 RID: 3288 RVA: 0x00039194 File Offset: 0x00037394
		public void FinalizeCheckpointMeasure()
		{
			this.elapsedTime = (float)this.checkpointStopwatch.ElapsedMilliseconds;
			this.checkpointStopwatch.Stop();
			using (StreamWriter streamWriter = new StreamWriter(ToolsHelper.GetScanOutPut() + "/MemCurve"))
			{
				foreach (PerformanceMeasurer.StatusCheckpoint statusCheckpoint in this.statusCheckpointList)
				{
					streamWriter.WriteLine(statusCheckpoint.ToString());
				}
			}
		}

		// Token: 0x040007D0 RID: 2000
		private PerformanceMeasurer.CurrentStatusState currentPerformanceBaseline = new PerformanceMeasurer.CurrentStatusState();

		// Token: 0x040007D1 RID: 2001
		private Stopwatch stateExecutionStopwatch = new Stopwatch();

		// Token: 0x040007D2 RID: 2002
		private Stack<PerformanceMeasurer.StateTracker> stateTrackerStack = new Stack<PerformanceMeasurer.StateTracker>();

		// Token: 0x040007D3 RID: 2003
		private Stopwatch checkpointStopwatch = new Stopwatch();

		// Token: 0x040007D4 RID: 2004
		private List<PerformanceMeasurer.StatusCheckpoint> statusCheckpointList = new List<PerformanceMeasurer.StatusCheckpoint>();

		// Token: 0x040007D5 RID: 2005
		private double maxCpuUsage;

		// Token: 0x040007D6 RID: 2006
		private double maxMemUsage;

		// Token: 0x040007D7 RID: 2007
		private float elapsedTime;

		// Token: 0x02000169 RID: 361
		public class StateTracker
		{
			// Token: 0x06000CDA RID: 3290 RVA: 0x0000696E File Offset: 0x00004B6E
			public StateTracker(string stateName)
			{
				this.stateName = stateName;
				this.snapshotList = new List<PerformanceMeasurer.PerformanceSnapshot>();
			}

			// Token: 0x06000CDB RID: 3291 RVA: 0x00039248 File Offset: 0x00037448
			public void RecordSnapshot(long ticks, long elapsedMilliseconds, double primaryValue, double secondaryValue)
			{
				bool flag = this.labelStack == null || this.labelStack.Count == 0;
				if (flag)
				{
					throw new Exception("LabelStack is null or empty");
				}
				PerformanceMeasurer.PerformanceSnapshot item = new PerformanceMeasurer.PerformanceSnapshot(this.labelStack.Pop(), ticks, elapsedMilliseconds, primaryValue, secondaryValue);
				bool flag2 = this.snapshotList == null;
				if (flag2)
				{
					throw new Exception("Has not initialized");
				}
				this.snapshotList.Add(item);
			}

			// Token: 0x06000CDC RID: 3292 RVA: 0x000392BC File Offset: 0x000374BC
			public void RecordStateStatus()
			{
				using (StreamWriter streamWriter = new StreamWriter(ToolsHelper.GetScanOutPut() + "/ModulePerformanceInfo.csv", true))
				{
					foreach (PerformanceMeasurer.PerformanceSnapshot performanceSnapshot in this.snapshotList)
					{
						streamWriter.WriteLine(this.stateName + "," + performanceSnapshot.ToString());
					}
				}
			}

			// Token: 0x040007D8 RID: 2008
			public string stateName;

			// Token: 0x040007D9 RID: 2009
			public List<PerformanceMeasurer.PerformanceSnapshot> snapshotList;

			// Token: 0x040007DA RID: 2010
			public Stack<string> labelStack = new Stack<string>();
		}

		// Token: 0x0200016A RID: 362
		public class CurrentStatusState
		{
			// Token: 0x06000CDD RID: 3293 RVA: 0x00006995 File Offset: 0x00004B95
			public void StartMeasurement()
			{
				this.primaryBaseValue = PerformanceMeasurer.CurrentStatusState.GetSecondMeasurement();
				this.secondaryBaseValue = PerformanceMeasurer.CurrentStatusState.GetFirstMeasurement();
			}

			// Token: 0x06000CDE RID: 3294 RVA: 0x00039364 File Offset: 0x00037564
			public double FirstMeasure()
			{
				return PerformanceMeasurer.CurrentStatusState.GetSecondMeasurement() - this.primaryBaseValue;
			}

			// Token: 0x06000CDF RID: 3295 RVA: 0x00039384 File Offset: 0x00037584
			public double SecondMeasure()
			{
				return PerformanceMeasurer.CurrentStatusState.GetFirstMeasurement() - this.secondaryBaseValue;
			}

			// Token: 0x06000CE0 RID: 3296 RVA: 0x000393A4 File Offset: 0x000375A4
			public static double GetFirstMeasurement()
			{
				return (double)Profiler.GetTotalAllocatedMemoryLong();
			}

			// Token: 0x06000CE1 RID: 3297 RVA: 0x000393BC File Offset: 0x000375BC
			public static double GetSecondMeasurement()
			{
				return (double)Profiler.GetMonoUsedSizeLong();
			}

			// Token: 0x040007DB RID: 2011
			private double primaryBaseValue;

			// Token: 0x040007DC RID: 2012
			private double secondaryBaseValue;
		}

		// Token: 0x0200016B RID: 363
		public struct StatusCheckpoint
		{
			// Token: 0x040007DD RID: 2013
			public string checkpointLabel;

			// Token: 0x040007DE RID: 2014
			public float checkpointTime;

			// Token: 0x040007DF RID: 2015
			public double primaryValue;

			// Token: 0x040007E0 RID: 2016
			public double secondaryValue;
		}

		// Token: 0x0200016C RID: 364
		public struct PerformanceSnapshot
		{
			// Token: 0x06000CE3 RID: 3299 RVA: 0x000069AE File Offset: 0x00004BAE
			public PerformanceSnapshot(string snapshotLabel, long snapshotTicks, long elapsedMilliseconds, double primaryValue, double secondaryValue)
			{
				this.snapshotLabel = snapshotLabel;
				this.snapshotTicks = snapshotTicks;
				this.elapsedMilliseconds = elapsedMilliseconds;
				this.primaryValue = primaryValue;
				this.secondaryValue = secondaryValue;
			}

			// Token: 0x06000CE4 RID: 3300 RVA: 0x000393D4 File Offset: 0x000375D4
			public override string ToString()
			{
				return string.Format("{0},{1},{2},{3},{4}", new object[]
				{
					this.snapshotLabel,
					this.snapshotTicks,
					this.elapsedMilliseconds,
					this.primaryValue,
					this.secondaryValue
				});
			}

			// Token: 0x040007E1 RID: 2017
			public string snapshotLabel;

			// Token: 0x040007E2 RID: 2018
			public long snapshotTicks;

			// Token: 0x040007E3 RID: 2019
			public long elapsedMilliseconds;

			// Token: 0x040007E4 RID: 2020
			public double primaryValue;

			// Token: 0x040007E5 RID: 2021
			public double secondaryValue;
		}
	}
}
